﻿using System.Net;
using System.Net.Http.Headers;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;
using rpc_service.core.support.assembly.il.trycatch;
using rpc_service.log;
using Microsoft.Extensions.Logging;

namespace rpc_service.core.support.assembly.il;

public abstract class ILBaseStep : ILHeader, ILStep
{
    private ILTryCatch _ilTryCatch = new ILTryCatch();
    
    public void Process(ILGenerator il, LocalBuilder result, Type type, MethodInfo targetMethod)
    {
        string httpMethod = targetMethod.GetCustomAttribute<RPCMethod>()!.Method;
        
        // 判断如果判断不通过直接弹出
        if (!isPass(httpMethod, targetMethod.ReturnType))
        {
            return;
        }

        LocalBuilder requestLocal = null;
        LocalBuilder responseLocal = null;
        LocalBuilder receiveStreamLocal = null;
        LocalBuilder readStreamLocal = null;
        
        _ilTryCatch.StartTryBlock(il);
        
        httpRequst(il, result, requestLocal, responseLocal, receiveStreamLocal, readStreamLocal, type, targetMethod);
        
        _ilTryCatch.CatchBlock(il);
        _ilTryCatch.FinallyBlock(il, requestLocal, responseLocal, receiveStreamLocal, readStreamLocal);
        _ilTryCatch.EndTryBlock(il);
    }
    
    protected abstract bool isPass(string httpMethod, Type returnType);
    
    protected abstract void httpRequst(
        ILGenerator il, 
        LocalBuilder result, 
        LocalBuilder requestLocal,
        LocalBuilder responseLocal,
        LocalBuilder receiveStreamLocal,
        LocalBuilder readStreamLocal, 
        Type targetType, 
        MethodInfo targetMethod);
}